home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Magazine / C_Tutorial / Part-3 / gadgets0.c < prev    next >
C/C++ Source or Header  |  1997-07-27  |  7KB  |  268 lines

  1. #include<exec/libraries.h>
  2. #include<intuition/intuition.h>
  3. #include<utility/tagitem.h>
  4. #include<graphics/text.h>
  5. #include<graphics/rastport.h>
  6. #include<intuition/screens.h>
  7. #include<libraries/gadtools.h>
  8.  
  9. #include<string.h>
  10. #include<stdio.h>
  11.  
  12. #include<clib/exec_protos.h>
  13. #include<clib/graphics_protos.h>
  14. #include<clib/intuition_protos.h>
  15. #include<clib/layers_protos.h>
  16. #include<clib/gadtools_protos.h>
  17.  
  18. /* The library base global variables */
  19. struct Library* GfxBase;
  20. struct Library* IntuitionBase;
  21. struct Library* LayersBase;
  22. struct Library* GadToolsBase;
  23.  
  24. /* Need to give prototypes for our functions */
  25. void handleIDCMP(struct Window*);
  26. int setClip(struct Window*);
  27. void removeClip(struct Window*);
  28. void setupWindow();
  29. void createWindow(struct Gadget*);
  30.  
  31. /* Some constants for the size of the window */
  32. #define MYWIN_WIDTH        (400)
  33. #define MYWIN_HEIGHT    (200)
  34.  
  35. /* Some constants for the position and size of our gadget */
  36. #define MYGAD_LEFT        (10)
  37. #define MYGAD_TOP            (5)
  38. #define MYGAD_WIDTH        (80)
  39. #define MYGAD_HEIGHT    (12)
  40. #define MYGAD_TEXT        ("Next Pen")
  41. #define MYGAD_ID            (0)
  42.  
  43. /* The top gap required around the gadgets */
  44. #define MYTOPGAP      (30)
  45.  
  46. /* The start of the program */
  47. void main()
  48. {
  49.     /* Open libraries... */
  50.     if(GfxBase = OpenLibrary("graphics.library",37))
  51.     {
  52.         if(IntuitionBase = OpenLibrary("intuition.library",37))
  53.         {
  54.             if(LayersBase = OpenLibrary("layers.library",37))
  55.             {
  56.                 if(GadToolsBase = OpenLibrary("gadtools.library",37))
  57.                 {
  58.                     /* Now do the real work */
  59.           setupWindow();
  60.                     CloseLibrary(GadToolsBase);
  61.                 }
  62.                 else
  63.                     printf("Error: could not open gadtools.library\n");
  64.                 CloseLibrary(LayersBase);
  65.             }
  66.             else
  67.                 printf("Error: could not open layers.library\n");
  68.             CloseLibrary(IntuitionBase);
  69.         }
  70.         else
  71.             printf("Error: could not open intuition.library\n");
  72.         CloseLibrary(GfxBase);
  73.     }
  74.     else
  75.         printf("Error: could not open graphics.library\n");
  76. }
  77.  
  78. /* Setup the window -- do the GadTools stuff */
  79. void setupWindow()
  80. {
  81.     struct Screen* scr;
  82.     /* We'll copy the visual information for the default public screen */
  83.   /* (usually, this is the Workbench screen) */
  84.     if(scr = LockPubScreen(NULL))
  85.     {
  86.         APTR vinfo;
  87.         /* Get the visual info so GadTools can render the gadgets nicely */
  88.         if(vinfo = GetVisualInfo(scr, TAG_DONE))
  89.         {
  90.             struct Gadget* glist;
  91.             struct Gadget* gad;
  92.             /* Start a GadTools gadget list */
  93.             glist = NULL;
  94.             if(gad = CreateContext(&glist))
  95.             {
  96.                 int offtop, offleft;
  97.                 struct TextAttr topazFont;
  98.                 struct NewGadget newgad;
  99.                 /* The offsets of our window borders */
  100.                 offleft = scr->WBorLeft;
  101.                 offtop = scr->WBorTop + (scr->Font->ta_YSize + 1);
  102.                 /* Setup font description for 8pt Topaz font */
  103.                 topazFont.ta_Name = "topaz.font";
  104.                 topazFont.ta_YSize = 8;
  105.                 topazFont.ta_Style = 0;
  106.                 topazFont.ta_Flags = 0;
  107.                 /* Setup our first gadget */
  108.                 newgad.ng_TextAttr         = &topazFont;
  109.                 newgad.ng_VisualInfo     = vinfo;
  110.                 newgad.ng_LeftEdge         = MYGAD_LEFT + offleft;
  111.                 newgad.ng_TopEdge         = MYGAD_TOP + offtop;
  112.                 newgad.ng_Width             = MYGAD_WIDTH;
  113.                 newgad.ng_Height             = MYGAD_HEIGHT;
  114.                 newgad.ng_GadgetText    = MYGAD_TEXT;
  115.                 newgad.ng_GadgetID        = MYGAD_ID;
  116.                 newgad.ng_Flags                = 0;
  117.                 /* Now create it and add it to our list */
  118.                 if(gad = CreateGadget(BUTTON_KIND, gad, &newgad, TAG_DONE))
  119.                     createWindow(glist);
  120.                 else
  121.                     printf("Error: could not create gadget(s)\n");
  122.                 /* Free the gadget */
  123.                 FreeGadgets(glist);
  124.             }
  125.             else
  126.                 printf("Error: could not create GadTools context\n");
  127.             FreeVisualInfo(vinfo);
  128.         }
  129.         else
  130.             printf("Error: could not get visual info\n");
  131.         UnlockPubScreen(NULL, scr);
  132.     }
  133.     else
  134.         printf("Error: could not lock public screen\n");
  135. }
  136.  
  137. /* Actually open the window, in the normal way */
  138. void createWindow(struct Gadget* glist)
  139. {
  140.     struct Window* win;
  141.     /* Open our window */
  142.     if(win = OpenWindowTags(NULL,
  143.                                                     WA_Width,        MYWIN_WIDTH,
  144.                                                     WA_Height,    MYWIN_HEIGHT,
  145.                                                     WA_Flags,        WFLG_CLOSEGADGET | WFLG_DRAGBAR | WFLG_REPORTMOUSE,
  146.                                                     WA_IDCMP,        IDCMP_CLOSEWINDOW | IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE | BUTTONIDCMP | IDCMP_REFRESHWINDOW,
  147.                                                     WA_Gadgets,    glist,
  148.                                                     TAG_DONE,        0))
  149.     {
  150.         /* If window opened, set clip region */
  151.         if(setClip(win))
  152.         {
  153.             /* Let GadTools refresh its bits of the window */
  154.             GT_RefreshWindow(win, NULL);
  155.             /* Now handle messages */
  156.             handleIDCMP(win);
  157.             removeClip(win);
  158.         }
  159.         else
  160.             printf("Error: could not set clip region on window\n");
  161.         CloseWindow(win);
  162.     }
  163.     else
  164.         printf("Error: could not open window\n");
  165. }
  166.  
  167. /* Our message handling code */
  168. void handleIDCMP(struct Window* win)
  169. {
  170.     char* text = "Hello World!";
  171.     int going = TRUE;
  172.     int drawing = FALSE;
  173.     UBYTE pen = 1;
  174.     SetAPen(win->RPort, pen);
  175.     /* Set the drawing mode to draw only the foreground of text, not the background */
  176.     SetDrMd(win->RPort, JAM1);
  177.     while(going)
  178.     {
  179.         struct IntuiMessage* intuimsg;
  180.         /* Wait for messages to arrive */
  181.         WaitPort(win->UserPort);
  182.         /* Messages have arrived: loop through all of them */
  183.         while(intuimsg = GT_GetIMsg(win->UserPort))
  184.         {
  185.             /* Act on this message... */
  186.             switch(intuimsg->Class)
  187.             {
  188.             case IDCMP_MOUSEBUTTONS:
  189.                 switch(intuimsg->Code)
  190.                 {
  191.                 case SELECTDOWN:
  192.                     drawing = TRUE;
  193.                     break;
  194.                 case SELECTUP:
  195.                     drawing = FALSE;
  196.                     break;
  197.                 }
  198.                 /* break; omitted so we draw on click, too */
  199.             case IDCMP_MOUSEMOVE:
  200.                 /* Don't draw on top gap which holds gadget */
  201.                 if(drawing && intuimsg->MouseY > win->BorderTop+MYTOPGAP)
  202.                 {
  203.                     Move(win->RPort, intuimsg->MouseX, intuimsg->MouseY);
  204.                     Text(win->RPort, text, strlen(text));
  205.                 }
  206.                 break;
  207.             case IDCMP_CLOSEWINDOW:
  208.                 going = FALSE;
  209.                 break;
  210.             case IDCMP_REFRESHWINDOW:
  211.                 /* You *MUST* remember to ask for and handle these refresh messages */
  212.                 GT_BeginRefresh(win);
  213.                 GT_EndRefresh(win, TRUE);
  214.                 break;
  215.             case IDCMP_GADGETUP:
  216.                 /* Our button was clicked!  Set foreground to next pen colour */
  217.                 pen++;
  218.                 SetAPen(win->RPort, pen);
  219.                 break;
  220.             }
  221.             /* Reply when finished with message */
  222.             GT_ReplyIMsg(intuimsg);
  223.         }
  224.     }
  225. }
  226.  
  227. /* Set a clip region on internal part of window */
  228. int setClip(struct Window* win)
  229. {
  230.     /* Make a new region */
  231.     struct Region* reg;
  232.     if(reg = NewRegion())
  233.     {
  234.         /* Make a rectangle that describes the inside of the window */
  235.         struct Rectangle rect;
  236.         rect.MinX = win->BorderLeft;
  237.         rect.MinY = win->BorderTop;
  238.         rect.MaxX = win->Width - win->BorderRight - 1;
  239.         rect.MaxY = win->Height - win->BorderBottom - 1;
  240.         /* Make the region equal to this rectangle */
  241.         if(OrRectRegion(reg, &rect))
  242.         {
  243.             /* Set the clip region on the window's layer */
  244.             InstallClipRegion(win->WLayer, reg);
  245.             /* Say we succeeded */
  246.             return TRUE;
  247.         }
  248.         else
  249.         {
  250.             /* Failed to set region, so delete it */
  251.             DisposeRegion(reg);
  252.         }
  253.     }
  254.     /* If we get this far they we've failed */
  255.     return FALSE;
  256. }
  257.  
  258. /* Remove the clip region from a window */
  259. void removeClip(struct Window* win)
  260. {
  261.     struct Region* reg;
  262.     if(reg = InstallClipRegion(win->WLayer, NULL))
  263.     {
  264.         /* If a clip region is installed it's our new one, so delete it */
  265.         DisposeRegion(reg);
  266.     }
  267. }
  268.